using System;
using System.Text;
using System.Collections.Generic;
using System.Reflection;
using ctem.kernel;
using ctem.kernel.logger;
using ctem.helpers;
using MCSharp;
using System.Threading;
using System.Runtime.Serialization;
using System.Runtime.Remoting.Messaging;

namespace    ctem.kernel.adbms
{
 using System;
using MCSharp;
using System.Threading;
using System.Runtime.Serialization;
using System.Runtime.Remoting.Messaging;

[Serializable()]
public  partial class Interpreter : ISerializable {

 //-------------- MCsharp functions -----------

 public Interpreter ( ) {
  mcsharp_initiate();
}

 public Interpreter ( SerializationInfo info, StreamingContext context ) {
  MCSharp.Serialization.UnPack ( info, context, this );
   }

 public void GetObjectData ( SerializationInfo info, StreamingContext context ) {
  MCSharp.Serialization.Pack ( info, context, this );
 }

 public void mcsharp_initiate ( ) {

  Monitor.Enter ( CommExec.Objects );
  int mcObjectNumber = CommExec.Objects.Count + 1;
  CommExec.Objects.Add ( mcObjectNumber, this );
  Monitor.Exit ( CommExec.Objects );

 }

ModelManager mm ;

 ILoggingManagment main_logger ;

 ILogger interp_logger ;

 public  Interpreter (  ModelManager mm,  ILoggingManagment main_logger )  {

   mcsharp_initiate();

    this.mm  = mm  ;
 this.main_logger  = main_logger  ;
 interp_logger  = main_logger.GetLogger( "Interpreter"  )  ;
 interp_logger.WriteMessage( MessagePriority.Debug  , "Interpreter OK"  )  ;


 }

public  bool Interpret (  string command,  channel  resultChannel )   {
   interp_logger.WriteMessage( MessagePriority.Debug  , "We begin interpretate a command: " + command  )  ;
 bool result = true  ;

  Tokens tokens = new Tokens( command  )  ;

  string token = tokens.Next  ;

  while ( token  != "COMMAND_END"   )
  {
   switch ( token   )
 { case "new"   :
   interp_CreationCommands( tokens  )  ;
 break  ;
case "set"   :
   interp_SetCommands( tokens  )  ;
 break  ;
case "get"   :
   interp_GetCommands( tokens  , resultChannel  )  ;
 break  ;
case "del"   :
   interp_DeletionCommands( tokens  )  ;
 break  ;
case "start"   :
   interp_StartModelling( tokens  )  ;
 break  ;
case "stop"   :
   interp_StopModelling( tokens  )  ;
 break  ;
case "pause"   :
   interp_TemporaryStopModelling( tokens  )  ;
 break  ;
case "unpause"   :
   interp_RunAfterTemporaryStopModelExecuter( tokens  )  ;
 break  ;
case "terminate"   :
   interp_TerminateModelling( tokens  )  ;
 result  = false  ;
 break  ;
case "offline"   :
   interp_OfflineModeSet( tokens  )  ;
 result  = true  ;
 break  ;
case "online"   :
   interp_OnlineModeSet( tokens  )  ;
 result  = true  ;
 break  ;
default :
  throw new Exception( "Íåîïîçíàííûé òîêåí " + token + " â êîììàíäå " + tokens  )  ;
  }

  token  = tokens.Next  ;
 }

  interp_logger.WriteMessage( MessagePriority.Debug  , "We have interpretated a command: " + command + " result= " + result  )  ;
 return result  ;
  }
 void interp_CreationCommands (  Tokens tokens )   {
   string token = tokens.Next  ;

  switch ( token   )
 { case "actor"   :
    {
   IActor actor = mm.CreateNewActor( tokens.Next  , tokens.Next  , tokens.Next  )  ;

  mm.AddNewActor( actor  )  ;
 break  ;
 }
case "link"   :
    {
   string full_name_output_port = tokens.Next  ;

  string full_name_start_actor = EntityNameHelper.FullActorNameFromFullMemberName( full_name_output_port  )  ;

  string full_name_input_port = tokens.Next  ;

  string full_name_finish_actor = EntityNameHelper.FullActorNameFromFullMemberName( full_name_input_port  )  ;

  mm.AddNewLink( full_name_start_actor  , full_name_output_port  , full_name_finish_actor  , full_name_input_port  )  ;
 break  ;
 }
 }

  }
 void interp_SetCommands (  Tokens tokens )   {
   string token = tokens.Next  ;

  switch ( token   )
 { case "param"   :
    {
   string full_name_param = tokens.Next  ;

  string full_name_host_actor = EntityNameHelper.FullActorNameFromFullMemberName( full_name_param  )  ;

  string short_name_param = EntityNameHelper.ShortMemberNameFromFullMemberName( full_name_param  )  ;

  if ( full_name_host_actor  == "ModelExecuter"   )
   interp_SetModelExecuterParam( short_name_param  , tokens  )  ;

  else
  {
   string data = tokens.Next  ;

  double res ;

  string param_type = mm.GetActorByName( full_name_host_actor  ).GetParamByName( short_name_param  ).type_name  ;

  if ( param_type  == "double"   )
   mm.GetActorByName( full_name_host_actor  ).GetParamByName( short_name_param  ).value  = Convert.ToDouble( data  )  ;

  else
 if ( param_type  == "int"   )
   mm.GetActorByName( full_name_host_actor  ).GetParamByName( short_name_param  ).value  = Convert.ToInt32( data  )  ;

  else
 mm.GetActorByName( full_name_host_actor  ).GetParamByName( short_name_param  ).value  = Convert.ToString( data  )  ;
 
 
 }
 
 break  ;
 }
default :
  break  ;
 }

  }
 void interp_GetCommands (  Tokens tokens,  channel  resultChannel )   {
   string token = tokens.Next  ;

  switch ( token   )
 { case "logger"   :
    {
   resultChannel.Send ( new object[] {  main_logger.GetLogger( tokens.Next  )   } )
  ;
 break  ;
 }
case "param"   :
    {
   interp_GetParamCommands( tokens  , resultChannel  )  ;
 break  ;
 }
case "all"   :
    {
   interp_GetAllCommands( tokens  , resultChannel  )  ;
 break  ;
 }
 }

  }
 void interp_GetParamCommands (  Tokens tokens,  channel  resultChannel )   {
   string token = tokens.Next  ;

  switch ( token   )
 { case "value"   :
    {
   string full_name_param = tokens.Next  ;

  string full_name_host_entity = EntityNameHelper.FullActorNameFromFullMemberName( full_name_param  )  ;

  string short_name_param = EntityNameHelper.ShortMemberNameFromFullMemberName( full_name_param  )  ;

  if ( full_name_param  == "ModelExecuter.state"   )
   resultChannel.Send ( new object[] {  mm.GetModelExecuterState( )   } )
  ;

  if ( full_name_param  == "Timer.time"   )
   resultChannel.Send ( new object[] {  ctem.kernel.Timer.GetCurrentTime( )   } )
  ;

  else
 if ( mm.IsActorName( full_name_host_entity  )   )
   resultChannel.Send ( new object[] {  mm.GetActorByName( full_name_host_entity  ).GetParamByName( short_name_param  ).value   } )
  ;

  else
  {
   resultChannel.Send ( new object[] {  mm.GetPortByName( full_name_host_entity  ).GetParamByName( short_name_param  ).value   } )
  ;
 }
 
 
 break  ;
 }
case "type"   :
    {
   string full_name_param = tokens.Next  ;

  string full_name_host_entity = EntityNameHelper.FullActorNameFromFullMemberName( full_name_param  )  ;

  string short_name_param = EntityNameHelper.ShortMemberNameFromFullMemberName( full_name_param  )  ;

  resultChannel.Send ( new object[] {  mm.GetActorByName( full_name_host_entity  ).GetParamByName( short_name_param  ).type_name   } )
  ;
 break  ;
 }
 }

  }
 void interp_GetAllCommands (  Tokens tokens,  channel  resultChannel )   {
   string token = tokens.Next  ;

  switch ( token   )
 { case "params"   :
    {
   string full_name_host_actor = tokens.Next  ;

  resultChannel.Send ( new object[] {  NamesOfParams( mm.GetActorByName( full_name_host_actor  ).GetParams( )  )   } )
  ;
 break  ;
 }
case "inports"   :
    {
   string full_name_host_actor = tokens.Next  ;

  resultChannel.Send ( new object[] {  NamesOfInPorts( mm.GetActorByName( full_name_host_actor  ).GetInPorts( )  )   } )
  ;
 break  ;
 }
case "outports"   :
    {
   string full_name_host_actor = tokens.Next  ;

  resultChannel.Send ( new object[] {  NamesOfOutPorts( mm.GetActorByName( full_name_host_actor  ).GetOutPorts( )  )   } )
  ;
 break  ;
 }
 }

  }
 void interp_DeletionCommands (  Tokens tokens )   {
   string token = tokens.Next  ;

  switch ( token   )
 { case "actor"   :
    {
   mm.DeleteActor( tokens.Next  )  ;
 break  ;
 }
case "link"   :
    {
   string full_name_start_port = tokens.Next  ;

  string full_name_finish_port = tokens.Next  ;

  string full_name_link = full_name_start_port + " -> " + full_name_finish_port  ;

  mm.DeleteLink( full_name_link  )  ;
 break  ;
 }
 }

  }
 void interp_SetModelExecuterParam (  string short_name_param,  Tokens tokens )   {
   switch ( short_name_param   )
 { case "EndTime"   :
    {
   mm.SetModelExecuterEndTime( Int32.Parse( tokens.Next  )  )  ;
 break  ;
 }
case "Speed"   :
    {
   mm.SetModelExecuterSpeed( Int32.Parse( tokens.Next  )  )  ;
 break  ;
 }
 }

  }
 void interp_OfflineModeSet (  Tokens tokens )   {
   mm.SetModelExecuterOfflineMode( )  ;
 }
 void interp_OnlineModeSet (  Tokens tokens )   {
   mm.SetModelExecuterOnlineMode( )  ;
 }
 void interp_StartModelling (  Tokens tokens )   {
   mm.StartModelExecuter( )  ;
 }
 void interp_StopModelling (  Tokens tokens )   {
   mm.StopModelExecuter( )  ;
 }
 void interp_TerminateModelling (  Tokens tokens )   {
   mm.TerminateModelExecuter( )  ;
 }
 void interp_TemporaryStopModelling (  Tokens tokens )   {
   mm.TemporaryStopModelExecuter( )  ;
 }
 void interp_RunAfterTemporaryStopModelExecuter (  Tokens tokens )   {
   mm.RunAfterTemporaryStopModelExecuter( )  ;
 }
}


}